<!--
粒子系统-飞机着火， 有问题。
 -->
<template>
  <div class="container">
    <div id="cesiumContainer"> </div>
  </div>
</template>

<script>
  export default {
    name: "cesiumviewer",
    data() {
      return {
        vi: {},
        start: {},
        stop: {}
      }
    },
    mounted() {
      var Cesium = this.Cesium;
      let viewer = new Cesium.Viewer("cesiumContainer", {
        animation: true, // 是否显示动画控件
        homeButton: false, // 是否显示home键
        geocoder: false, // 是否显示地名查找控件
        baseLayerPicker: false, // 是否显示图层选择控件
        timeline: true, // 是否显示时间线控件
        fullscreenButton: true, // 是否全屏显示
        infoBox: true, // 是否显示点击要素之后显示的信息
        sceneModePicker: false, // 是否显示投影方式控件  三维/二维
        navigationInstructionsInitiallyVisible: false,
        navigationHelpButton: false, // 是否显示帮助信息控件
        orderIndependentTranslucency: false,
        shouldAnimate: true,
        scene3DOnly: false, // 每个几何实例将只能以3D渲染以节省GPU内存
        selectionIndicator: false // 取消点击有绿框
      });
      viewer._cesiumWidget._creditContainer.style.display = "none";

      let start = this.start
      start = Cesium.JulianDate.fromDate(new Date(2015, 2, 25, 16));
      stop = Cesium.JulianDate.addSeconds(start, 360, new Cesium.JulianDate());

      viewer.clock.startTime = start.clone();
      viewer.clock.stopTime = stop.clone();
      viewer.clock.currentTime = start.clone();
      viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
      viewer.clock.multiplier = 1;
      viewer.timeline.zoomTo(start, stop);


      var circularPosition = this.computeCirclularFlight(-112.110693, 36.0994841, 0.03);
      // var circularPosition = computeCirclularFlight(0, 0, 36000000); // 禁止卫星
      var staticPosition = Cesium.Cartesian3.fromDegrees(-112.110693, 36.0994841, 1000);

      // 模型
      var entity = viewer.entities.add({
        availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
          start: start,
          stop: stop
        })]),
        model: {
          uri: '../../static/models/Cesium_Air.gltf',
          minimumPixelSize: 64
        },
        position: circularPosition,
        orientation: new Cesium.VelocityOrientationProperty(circularPosition),
        // position: staticPosition, // ==stop fly
        // orientation: undefined
        path: {
          resolution: 1,
          material: new Cesium.PolylineGlowMaterialProperty({
            glowPower: 0.2,
            color: Cesium.Color.YELLOW
          }),

          width: 10
        }
      });
      // entity.position.setInterpolationOptions({
      //     interpolationDegree : 5,
      //     interpolationAlgorithm : Cesium.LagrangePolynomialApproximation
      // });
      viewer.trackedEntity = entity;

      // 粒子系统
      var particleSystem = viewer.scene.primitives.add(new Cesium.ParticleSystem({
        image: '../../static/models/fire.png', // 粒子资源，用于广告牌的URI，HTMLImageElement或HTMLCanvasElement。
        startColor: Cesium.Color.RED.withAlpha(0.7), //粒子出生时的颜色
        endColor: Cesium.Color.YELLOW.withAlpha(0.3), //当粒子死亡时的颜色
        startScale: 1, //粒子出生时的比例，相对于原始大小
        endScale: 4, //粒子在死亡时的比例
        life: 1, //以秒为单位设置粒子的最小和最大寿命
        // minimumLife: 1, //以秒为单位设置粒子的最短寿命
        // maximumLife: 1, //以秒为单位设置粒子的最大寿命
        speed: 5, //设置以米/秒为单位的最小和最大速度
        // minimumSpeed: 5, //设置以米/秒为单位的最小速度
        // maximumSpeed: 5, //设置以米/秒为单位的最大速度
        width: 20, // 设置以像素为单位的粒子的最小和最大宽度
        // minimumWidth: viewModel.particleSize, //设置粒子的最小宽度（以像素为单位）。
        // maximumWidth: viewModel.particleSize, //设置粒子的最大宽度（以像素为单位）。
        height: 20, //设置粒子的最小和最大高度（以像素为单位）。
        // minimumHeight: viewModel.particleSize, //设置粒子的最小高度（以像素为单位）。
        // maximumHeight: viewModel.particleSize, //设置粒子的最大高度（以像素为单位）。
        rate: 10, //每秒发射的粒子数量
        // bursts: [
        //     // time：在粒子系统生命周期开始之后的几秒钟内将发生突发事件。
        //     // minimum：突发中发射的最小粒子数量
        //     // maximum：突发中发射的最大粒子数量
        //     // new Cesium.ParticleBurst({time: 5.0, minimum: 1, maximum: 10}),   // 当在5秒时，发射的数量为50-100
        //     // new Cesium.ParticleBurst({time: 10.0, minimum: 1, maximum: 10}), // 当在10秒时，发射的数量为200-300
        //     // new Cesium.ParticleBurst({time: 15.0, minimum: 1, maximum: 10})  // 当在15秒时，发射的数量为500-800
        //     new Cesium.ParticleBurst({time: 5.0, minimum: 50, maximum: 100}),   // 当在5秒时，发射的数量为50-100
        //     new Cesium.ParticleBurst({time: 10.0, minimum: 100, maximum: 200}), // 当在10秒时，发射的数量为200-300
        //     new Cesium.ParticleBurst({time: 15.0, minimum: 200, maximum: 300})  // 当在15秒时，发射的数量为500-800
        // ], //数组ParticleBurst，周期性地发射粒子脉冲串
        lifeTime: 16, //多长时间的粒子系统将以秒为单位发射粒子
        loop: true, //是否粒子系统应该在完成时循环它的爆发
        // new Cesium.CircleEmitter(0.5)
        // new Cesium.BoxEmitter(new Cesium.Cartesian3(0.1, 0.1, 0.1))
        // new Cesium.ConeEmitter(Cesium.Math.toRadians(30.0))
        emitter: new Cesium.CircleEmitter(
          0.5), //此系统的粒子发射器  共有 BoxEmitter,CircleEmitter,ConeEmitter,SphereEmitter 几类
        emitterModelMatrix: this.computeEmitterModelMatrix(), // 4x4转换矩阵，用于在粒子系统本地坐标系中转换粒子系统发射器
        modelMatrix: this.computeModelMatrix(entity, Cesium.JulianDate.now()), // 4x4转换矩阵，可将粒子系统从模型转换为世界坐标
        forces: this.applyGravity // 强制回调函数--例子：这是添加重力效果
      }));
      var f1 = this.computeModelMatrix;
      var f2 = this.computeEmitterModelMatrix;
      // 当场景运动起来时，粒子系统要实时计算位置，静止的场景可以省略这个
      viewer.scene.preRender.addEventListener(function(scene, time) {
        particleSystem.modelMatrix = f1(entity, time);
        particleSystem.emitterModelMatrix = f2();
      });
    },
    methods: {
      // 模型位置
      computeModelMatrix(entity, time) {
        let Cesium = this.Cesium
        var position = Cesium.Property.getValueOrUndefined(entity.position, time, new Cesium.Cartesian3());
        if (!Cesium.defined(position)) {
          return undefined;
        }
        var orientation = Cesium.Property.getValueOrUndefined(entity.orientation, time, new Cesium.Quaternion());
        var modelMatrix = null;
        if (!Cesium.defined(orientation)) {
          modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position, undefined, new Cesium.Matrix4());
        } else {
          modelMatrix = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix3.fromQuaternion(orientation, new Cesium
            .Matrix3()), position, modelMatrix);
        }
        return modelMatrix;
      },

      // 粒子发射系统的模型位置
      computeEmitterModelMatrix() {
        let Cesium = this.Cesium
        var hpr = Cesium.HeadingPitchRoll.fromDegrees(0, 0, 0, new Cesium.HeadingPitchRoll());
        var trs = new Cesium.TranslationRotationScale();
        trs.translation = Cesium.Cartesian3.fromElements(2.5, 4.0, 1.0, new Cesium.Cartesian3()); // 设置粒子系统相对于模型坐标的偏移
        trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr, new Cesium.Quaternion());
        return Cesium.Matrix4.fromTranslationRotationScale(trs, new Cesium.Matrix4());
      },

      computeCirclularFlight(lon, lat, radius) {
        let Cesium = this.Cesium
        var property = new Cesium.SampledPositionProperty();
        for (var i = 0; i <= 360; i += 45) {
          var radians = Cesium.Math.toRadians(i);
          var time = Cesium.JulianDate.addSeconds(this.start, i, new Cesium.JulianDate());
          var position = Cesium.Cartesian3.fromDegrees(lon + (radius * 1.5 * Math.cos(radians)), lat + (radius * Math
            .sin(radians)), Cesium.Math.nextRandomNumber() * 500 + 1750);
          property.addSample(time, position);
        }
        return property;
      },
      applyGravity(particle, dt) {
        let Cesium = this.Cesium
        var position = particle.position;
        var gravityVector = Cesium.Cartesian3.normalize(position, new Cesium.Cartesian3());
        Cesium.Cartesian3.multiplyByScalar(gravityVector, -20 * dt, gravityVector); // 设置重力效果大小 -20时效果比较明显
        particle.velocity = Cesium.Cartesian3.add(particle.velocity, gravityVector, particle.velocity);
      }

    }
  }
</script>

<style scoped="scoped">
  .container {
    width: 100%;
    height: 100%;
  }

  #cesiumContainer {
    width: 100%;
    height: 100%;
    position: absolute;
    margin: 0;
    padding: 0;
    /*  overflow: hidden; */
  }
</style>
